import axios from 'axios'
import { Promise } from 'core-js'
import { Message } from 'element-ui'
import { getTimeStamp } from '@/utils/auth'
// 引入vuex
import store from '@/store'
// 引入路由
import router from '@/router'

const TimeOutDuration = 2000

const service = axios.create({
  baseURL: process.env.VUE_APP_BASE_API,
  timeout: 5000
})

// 请求拦截器 在每个请求 headers 带上 token (如果请求本身没有带, 但是数据中有 token)
service.interceptors.request.use(config => {
  // 如果请求本身没有带上 token 但是 vuex 里面存在, 就应该默认注入
  if (!config.headers.Authorization && store.getters.token) {
    // 这里是 JWT 鉴权标准的 Bearer Token 规范
    // 格式是: 'Bearer xxxxxx'
    // 在注入之前, 先判断一下是否已经过期
    if (!isTimeOut()) {
    // 这里是 JWT 鉴权标准的 Bearer Token 规范
    // 格式是: 'Bearer xxxxxx'
      config.headers.Authorization = `Bearer ${store.getters.token}`
    } else {
    // 这里是已经过期的状况
    // 登出操作删除数据
      store.dispatch('user/logout')
      // 跳回登录页
      router.push('/login')
      // return Promise.reject 停止请求
      return Promise.reject(new Error('登录已过期'))
    }
  }
  return config
}, err => {
  // 防御性编程, 处理可能出现的报错
  Message.error(err.message)
  return Promise.reject(new Error(err.message))
})
// 响应拦截器
service.interceptors.response.use(
  res => {
    const { success, message, data } = res.data
    if (success) {
      return data
    } else {
      Message.error(message)
      return Promise.reject(new Error(message))
    }
  }, err => {
    console.log(err)
    console.log('拦截器失败逻辑')
    console.dir(err)
    // 这里是网络层面的失败, 以前都是用来处理断网, 写错url 之类
    // 现在多了一种可能性, 就是 token 失效
    // 这里就应该做判断, 如果是 code === 10002
    if (err.response && err.response.data && err.response.data.code === 10002) {
    // 退出
    // 做登出和跳转操作
      store.dispatch('user/logout')
      router.push('/login')
    } else {
    // 其他的处理
      console.dir(err)
      Message.error(err.message)
    }
    return Promise.reject(new Error(err.message))
  }
)
function isTimeOut() {
  const currentTime = Date.now()
  const timeStamp = getTimeStamp()
  return (currentTime - timeStamp) / 1000 > TimeOutDuration
}

export default service
